package org.xm.sk.filter.auth;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
import org.xm.sk.service.security.JwtTokenUtil;
import org.xm.sk.service.security.XmUser;


@Component  
@WebFilter(urlPatterns={"/*"}, filterName="authHeaderFilter")
public class AuthHeaderFilter implements Filter {

    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private UserDetailsService userDetailsService;

    @Value("${jwt.header}")
    private String header;

    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        
        response.setHeader("Access-Control-Expose-Headers", "authorization");
        String refreshedToken = null;
        String oldToken = request.getHeader(header);
        if (null == oldToken) {
            chain.doFilter(req, res);
            return;
        }
        final String token = oldToken.substring(tokenHead.length());
        String username = jwtTokenUtil.getUsernameFromToken(token);
        if (null == username) {
            chain.doFilter(req, res);
            return;
        }
        XmUser user = (XmUser) userDetailsService.loadUserByUsername(username);
        if (null == user) {
            chain.doFilter(req, res);
            return;
        }
        if (jwtTokenUtil.canTokenBeRefreshed(token,
                user.getLastPasswordResetDate())) {
            refreshedToken = jwtTokenUtil.refreshToken(token);
        }
        if (null == refreshedToken) {
            chain.doFilter(req, res);
            return;
        }
        response.setHeader(header, tokenHead + refreshedToken);
        chain.doFilter(req, res);
    }

    @Override
    public void destroy() {
    }

}
